/* This class represents a single display item containing information about a document.
*
* docInfo - DocInfo object containing information about the document
+ * currentSeconds - current number of seconds since the epoch
* availableWidth - total width available for the item
*/
-function DocDisplayItem(docInfo, availableWidth) {
- this._init(docInfo, availableWidth);
+function DocDisplayItem(docInfo, currentSecs, availableWidth) {
+ this._init(docInfo, currentSecs, availableWidth);
}
DocDisplayItem.prototype = {
__proto__: GenericDisplay.GenericDisplayItem.prototype,
- _init : function(docInfo, availableWidth) {
- GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
+ _init : function(docInfo, currentSecs, availableWidth) {
+ GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
this._docInfo = docInfo;
-
+
this._setItemInfo(docInfo.name, "");
+ // We take the current number of seconds here to avoid looking up the current
+ // time for every item
+ this._resetTimeDisplay(currentSecs);
},
//// Public methods ////
+ getUpdateTimeout: function() {
+ return this._timeout;
+ },
+
+ // Update any relative-time based displays for this item.
+ redisplay: function(currentSecs) {
+ this._resetTimeDisplay(currentSecs);
+ },
+
//// Public method overrides ////
// Opens a document represented by this display item.
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
this._docInfo.uri, availableWidth, availableHeight);
+ },
+
+ //// Private Methods ////
+
+ _resetTimeDisplay: function(currentSecs) {
+ let lastSecs = this._docInfo.lastVisited().getTime() / 1000;
+ let timeDelta = currentSecs - lastSecs;
+ let [text, nextUpdate] = Shell.Global.get().format_time_relative_pretty(timeDelta);
+ this._timeout = nextUpdate;
+ this._setDescriptionText(text);
}
};
GenericDisplay.GenericDisplay.prototype._init.call(this, width);
let me = this;
+ this._updateTimeoutTarget = 0;
+ this._updateTimeoutId = 0;
+
this._docManager = DocInfo.getDocManager(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
this._docsStale = true;
this._docManager.connect('changed', function(mgr, userData) {
// but redisplaying right away is cool when we use Zephyr.
// Also, we might be displaying remote documents, like Google Docs, in the future
// which might be edited by someone else.
- me._redisplay(false);
+ me._redisplay(false);
});
+
+ this.connect('destroy', Lang.bind(this, function (o) {
+ if (this._updateTimeoutId > 0)
+ Mainloop.source_remove(this._updateTimeoutId);
+ }));
},
//// Protected method overrides ////
// Creates a DocDisplayItem based on itemInfo, which is expected to be a DocInfo object.
_createDisplayItem: function(itemInfo, width) {
- return new DocDisplayItem(itemInfo, width);
+ let currentSecs = new Date().getTime() / 1000;
+ let doc = new DocDisplayItem(itemInfo, currentSecs, width);
+ if (doc.getUpdateTimeout() < this._updateTimeoutTarget) {
+ if (this._updateTimeoutId > 0)
+ Mainloop.source_remove(this._updateTimeoutId);
+ this._updateTimeoutId = Mainloop.timeout_add_seconds(doc.getUpdateTimeout(), Lang.bind(this, this._docTimeout));
+ this._updateTimeoutTarget = doc.getUpdateTimeout();
+ }
+ return doc;
+ },
+
+ //// Private Methods ////
+ _docTimeout: function () {
+ let currentSecs = new Date().getTime() / 1000;
+ for (let docId in this._allItems) {
+ let doc = this._allItems[docId];
+ doc.redisplay(currentSecs);
+ }
+ return true;
}
};
#include <unistd.h>
#include <dbus/dbus-glib.h>
#include <gio/gio.h>
+#include <glib/gi18n.h>
#include <math.h>
#include <X11/extensions/Xfixes.h>
global->root_pixmap = NULL;
}
+/**
+ * shell_global_format_time_relative_pretty:
+ * @global:
+ * @delta: Time in seconds since the current time
+ * @text: (out): Relative human-consumption-only time string
+ * @next_update: (out): Time in seconds until we should redisplay the time
+ *
+ * Format a time value for human consumption only. The passed time
+ * value is a delta in terms of seconds from the current time.
+ */
+void
+shell_global_format_time_relative_pretty (ShellGlobal *global,
+ guint delta,
+ char **text,
+ guint *next_update)
+{
+#define MINUTE (60)
+#define HOUR (MINUTE*60)
+#define DAY (HOUR*24)
+#define WEEK (DAY*7)
+ if (delta < MINUTE) {
+ *text = g_strdup (_("Less than a minute ago"));
+ *next_update = MINUTE - delta;
+ } else if (delta < HOUR) {
+ *text = g_strdup_printf (ngettext ("%d minute ago", "%d minutes ago", delta / MINUTE), delta / MINUTE);
+ *next_update = MINUTE*(delta-MINUTE + 1) - delta;
+ } else if (delta < DAY) {
+ *text = g_strdup_printf (ngettext ("%d hour ago", "%d hours ago", delta / HOUR), delta / HOUR);
+ *next_update = HOUR*(delta-HOUR + 1) - delta;
+ } else if (delta < WEEK) {
+ *text = g_strdup_printf (ngettext ("%d day ago", "%d days ago", delta / DAY), delta / DAY);
+ *next_update = DAY*(delta-DAY + 1) - delta;
+ } else {
+ *text = g_strdup_printf (ngettext ("%d week ago", "%d weeks ago", delta / WEEK), delta / WEEK);
+ *next_update = WEEK*(delta-WEEK + 1) - delta;
+ }
+}
+
/**
* shell_global_create_root_pixmap_actor:
* @global: a #ShellGlobal